package iris_controller

import (
	"fmt"
	"github.com/kataras/iris/v12"
	domain "gluenet/internal/glue-srvp/domain"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
	"gluenet/pkg/log"
)

func init() {
	prepare.RegisterAuthController(func() {
		controller := NewInstanceController()
		prepare.InjectAuthController(func() *Instance {
			return controller
		})
	})
}

type Instance struct {
	Instance *domain.Instance
}

func NewInstanceController() *Instance {
	r := &Instance{}
	prepare.FetchDependency(&r.Instance)
	return r
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/all
func (c *Instance) GetAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	objs, err := c.Instance.FindBy(auth, map[string]interface{}{})

	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/query
func (c *Instance) GetQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var query = make(map[string]interface{}, len(ctx.URLParams()))
	for k, v := range ctx.URLParams() {
		query[k] = v
	}
	cfg, err := c.Instance.FindBy(auth, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(cfg)
}

//// Get serves
//// Method:   GET
//// Resource: http://localhost:8080/apis/instance/all/runtime/list
//func (c *Instance) GetAllRuntimeList(ctx iris.Context) *infra.Response {
//	var auth = infra.AuthInfo{}
//	auth.UserId = ctx.Values().GetString("user_id")
//	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
//	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")
//
//	objs, err := c.Instance.FindRuntime(auth, map[string]interface{}{})
//	if err != nil {
//		return infra.ResponseReqErr(err, nil)
//	}
//	return infra.ResponseOK(objs)
//}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/runtime/all
func (c *Instance) GetRuntimeAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	objs, err := c.Instance.FindRuntime(auth, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/runtime/childinfo
func (c *Instance) GetRuntimeChildinfo(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	objs, err := c.Instance.FindRuntimeChildInfo(auth, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/links
func (c *Instance) GetLinks(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")

	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	cfg, err := c.Instance.GetLinks(auth, guid)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(cfg)
}

// Get serves
// Method:   POST
// Resource: http://localhost:8080/apis/instance/links/set
func (c *Instance) PostLinksSet(ctx iris.Context) *infra.Response {
	var links struct {
		StrategyGuid string   `json:"strategy_guid"`
		AppsGuid     []string `json:"application_guids"`
	}
	if err := ctx.ReadJSON(&links); err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	fmt.Println(links)

	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	if err := c.Instance.DeleteAllLinks(auth, links.StrategyGuid); err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	var linkRes = vo.LinkSetRes{}
	for _, app := range links.AppsGuid {
		link, err := c.Instance.CreateLinks(auth, links.StrategyGuid, app)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
		linkRes.Links = append(linkRes.Links, link)
	}

	res, err := c.Instance.InfoStrategy(auth, links.StrategyGuid, links.AppsGuid)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("info strategy %v", err), nil)
	} else {
		log.Infof("info succeed %v", res)
	}

	return infra.ResponseOK(linkRes)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/instance/create
func (c *Instance) PostCreate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	req := vo.CreateInstanceReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	ins, err := c.Instance.Create(auth, req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(ins)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/instance/update
func (c *Instance) PostUpdate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	req := vo.UpdateInstanceReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	obj, err := c.Instance.Update(auth, req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(obj)
}

// Create serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/instance/delete
func (c *Instance) DeleteDelete(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = map[string][]int64{}
	err := ctx.ReadJSON(&req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	if _, ok := req["ids"]; !ok {
		return infra.ResponseReqErr(fmt.Errorf("need ids"), nil)
	}

	for _, id := range req["ids"] {
		if _, err = c.Instance.Remove(auth, id); err != nil {
			return infra.ResponseReqErr(fmt.Errorf("delete %d %v", id, err), nil)
		}
	}
	return infra.ResponseOK(nil)
}

func (c *Instance) GetUpdateContainer(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	err := c.Instance.UpdateInstanceContainer(auth)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(nil)
}
